package com.hc.springbootrabbitmq.service;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

//RabbitMQ消息消费方
@Service
public class RabbitMQService {
//      @RabbitListener注解用于监听某个队列中的消息,当有消息时自动调用方法,并传递Message参数值
//    @RabbitListener(queues = "fanout_queue_email")
//    public void f1receiveEmailMessage(Message message){
//        byte[] body = message.getBody();
//        System.out.println("发布订阅模式消费方监听到邮件数据：" + new String(body));
//    }
//
//    @RabbitListener(queues = "fanout_queue_sms")
//    public void f1receiveSmsMessage(Message message){
//        byte[] body = message.getBody();
//        System.out.println("发布订阅模式消费方监听到短信数据：" + new String(body));
//    }

    //发布订阅模式基于注解的方式的实现组件配置
    @RabbitListener(bindings = @QueueBinding(value = @Queue("fanout_queue_email"),
            exchange = @Exchange(value = "fanout_exchange",type = "fanout")))
    public void f1receiveEmailMessage(Message message){
        byte[] body = message.getBody();
        System.out.println("发布订阅模式消费方监听到邮件数据：" + new String(body));
    }

    @RabbitListener(bindings = @QueueBinding(value = @Queue("fanout_queue_sms"),
            exchange = @Exchange(value = "fanout_exchange",type = "fanout")))
    public void f1receiveSmsMessage(Message message){
        byte[] body = message.getBody();
        System.out.println("发布订阅模式消费方监听到短信数据：" + new String(body));
    }
    //路由模式基于注解方式实现组件配置。key指定路由键,对队列进行标记,并接收匹配的消息
    @RabbitListener(bindings = @QueueBinding(value = @Queue("route_queue_error"),
            exchange = @Exchange(value = "route_exchange",type = "direct"),
            key = "route_key_error"))
    public void routeError(String msg){
        System.out.println("路由模式错误队列接收到消息:" + msg);
    }
    @RabbitListener(bindings = @QueueBinding(value = @Queue("route_queue_info"),
            exchange = @Exchange(value = "route_exchange",type = "direct"),
            key = {"route_key_info","route_key_error"}))
    public void routeInfo(String msg){
        System.out.println("路由模式信息队列接收到消息:" + msg);
    }
    //主题模式基于注解方式实现组件配置 #任意个字符 *一个字符
    @RabbitListener(bindings = @QueueBinding(value = @Queue("topic_queue_email"),
            exchange = @Exchange(value = "topic_exchange",type = "topic"),
            key = "info.#.email.#"))
    public void topicEmail(String msg){
        System.out.println("主题模式金接收email消息:" + msg);
    }

    @RabbitListener(bindings = @QueueBinding(value = @Queue("topic_queue_sms"),
            exchange = @Exchange(value = "topic_exchange",type = "topic"),
            key = "info.#.sms.*"))
    public void topicSMS(String msg){
        System.out.println("主题模式金接收sms消息:" + msg);
    }

//    @RabbitListener(queues = "simple_queue")
//    public void simple(String msg){
//        System.out.println("简单模式接收消息" + msg);
//    }
//
//    @RabbitListener(queues = "work_queue")
//    public void workConsumer1(String message){
//        System.out.println("工作队列模式1接收消息" + message);
//    }
//
//    @RabbitListener(queues = "work_queue")
//    public void workConsumer2(String message){
//        System.out.println("工作队列模式2接收消息" + message);
//    }

    //@Queue(value = "route_queue_error",autoDelete = "true")
    //autoDelete=true 当检测到消费方与队列断开连接且队列没有消费方时,则该队列会自动删除
    //@Exchange(value = "topic_exchange",type = "topic",autoDelete = "true")
    //autoDelete=true 当检测到全部绑定队列不再使用时,则该交换机会自动删除

    //限流手动签收
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "manual_direct_queue_email"),
            exchange = @Exchange(value = "manual_direct_exchange"),
            key = "manual_direct_key_email"))
    public void manual(Message message, Channel channel) throws Exception {
        //Channel表示消息管道,封装相关消息的配置信息,用于返回确认信息
        long id = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(id,true);
        System.out.println("限流接收到消息:" + new String(message.getBody()));
    }
}
